Option Explicit On
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Text

Public Class NumericTextBox
	Inherits System.Web.UI.WebControls.TextBox

	Private _DecimalPlaces As Int32 = 0
	Private _AllowDecimal As Boolean
	Private _AllowNegative As Boolean

	Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)

		MyBase.OnPreRender(e)

		Dim decPlaces As Int32
        If Me.AllowDecimal Then
            decPlaces = Me.DecimalPlaces
        End If

		'Apply customer class (must be defined in containing page) if property set
		If Me.CSSClassCustom <> "" Then
			Me.CssClass = Me.CSSClassCustom
		Else	'Default to align right
			Me.Style.Clear()
			Me.Style.Add("text-align", "right")	'Default to align right.  -RL 03/2009
		End If

		'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		'~~THIS WILL NOT REGISTER IF THE CONTROL IS ONLY INSIDE AN AJAX UPDATE PANEL.  USE STYLES
		'~~TO HIDE A CONTROL OUTSIDE OF THE UPDATE PANEL.  -RL 1/09
		'
		'~~Register NumericTextBox.js JavaScript file from the embedded resource.  See AssemblyInfo.vb.
		'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		If Not Parent.Page.ClientScript.IsClientScriptBlockRegistered(Page.GetType, "NumericValidation") Then
			Dim jsPath As String = Parent.Page.ClientScript.GetWebResourceUrl(Me.GetType, "LZDollarTextBox.NumericTextBox.js")
			Parent.Page.ClientScript.RegisterClientScriptInclude("NumericValidation", jsPath)
		End If

        'Added onfocus/onblur code to track for changes and fire onchange event.  Had to do this to get onchange to work.

        'Save user defined onblur/onfocus events and execute after our internal onblur/onfocus
        If Not Me.Attributes("onBlur") Is Nothing Then Me.Attributes.Add("onblur1", Me.Attributes("onblur").ToString)
        Me.Attributes("onBlur") = "textbox_onblur(this);"   'executes user defined onblur after our onblur code.
        If Not Me.Attributes("onFocus") Is Nothing Then Me.Attributes.Add("onfocus1", Me.Attributes("onblur").ToString)
        Me.Attributes("onFocus") = "textbox_onfocus(this);"   'executes user defined onblur after our onblur code.

        If Me.CanWrite Then            
            Me.Attributes.Add("onkeyup", "extractNumber(this, event, " & decPlaces & ", " & _AllowNegative.ToString.ToLower & ", " & Me.NumberGrouping.ToString.ToLower & ", " & Me.DollarSign.ToString.ToLower & ");")
            Me.Attributes.Add("onkeypress", "return blockNonNumbers(this, event," & _AllowDecimal.ToString.ToLower & "," & _AllowNegative.ToString.ToLower & ", " & Me.NumberGrouping.ToString.ToLower & ", " & Me.DollarSign.ToString.ToLower & ");")
            Me.Attributes.Add("onpaste", "return false;")   'disallow pasteing.  Seems to work on modern browsers
        Else    'don't allow changes.  This method will allow changes via javascript that appear in postbacks. -RL 07/2009
            Me.Attributes.Add("onkeypress", "return false;")
            Me.Attributes.Add("readOnly", "True")
            Me.Style("cursor") = "default"
            Me.BackColor = Drawing.Color.WhiteSmoke
            Me.TabIndex = -1
        End If
		
        If Me.OnClientChange <> "" Then Me.Attributes.Add("onblur", Me.OnClientChange)

	End Sub

#Region "Properties"

	'override the Text property to remove all non numerics
	Public Overrides Property Text() As String
		Get
            'Return MyBase.Text
            Dim value As String = MyBase.Text

            If IsNumeric(value) Then
                If Me.NumberGrouping Then
                    If Me.DollarSign Then
                        value = FormatCurrency(value, Me.DecimalPlaces, , , TriState.True).ToString
                    Else
                        value = FormatNumber(value, Me.DecimalPlaces, , , TriState.True).ToString
                    End If
                Else    'No number grouping
                    If Me.DollarSign Then
                        value = FormatCurrency(value, Me.DecimalPlaces, , , TriState.False).ToString
                    Else
                        value = FormatNumber(value, Me.DecimalPlaces, , , TriState.False).ToString
                    End If
                End If
            Else    'Non numeric values are not valid
                value = "0"
            End If
            Return value
		End Get
        Set(ByVal value As String)
            'MOVED FORMATTING TO GET -RL 7/2009            
            MyBase.Text = value
        End Set
	End Property

	Public ReadOnly Property TextCLEAN() As String
		Get
			Dim sVal As String = MyBase.Text
			If Not IsNothing(sVal) Then
				sVal = System.Text.RegularExpressions.Regex.Replace(sVal, "[^0-9.-]", "").ToString
				If Not IsNumeric(sVal) Then sVal = 0
			Else
				sVal = 0
			End If
			Return sVal
		End Get
	End Property

	Private vOnClientChange As String = ""
	Public Property OnClientChange() As String
		Get
			Return vOnClientChange
		End Get
		Set(ByVal Value As String)
			vOnClientChange = Value
		End Set
	End Property

	Private vCSSClassCustom As String = ""
	Public Property CSSClassCustom() As String
		Get
			Return vCSSClassCustom
		End Get
		Set(ByVal Value As String)
			vCSSClassCustom = Value
			MyBase.CssClass = Value
		End Set
	End Property

	Private vTag As String = ""
	Public Property Tag() As String
		Get
			Return vTag
		End Get
		Set(ByVal Value As String)
			vTag = Value
		End Set
	End Property

	Private vCanWrite As Boolean = True
	Public Property CanWrite() As Boolean
		Get
			Return vCanWrite
		End Get
		Set(ByVal Value As Boolean)
			vCanWrite = Value
		End Set
	End Property

	Public Property DecimalPlaces() As Int32
		Get
			Return _DecimalPlaces
		End Get
		Set(ByVal Value As Int32)
			_DecimalPlaces = Value
		End Set
	End Property

	Public Property AllowDecimal() As Boolean
		Get
			Return _AllowDecimal
		End Get
		Set(ByVal Value As Boolean)
			'Set defaults for # dec places
			If Value = False Then
				Me.DecimalPlaces = 0
			Else
				Me.DecimalPlaces = 2
			End If
			_AllowDecimal = Value
		End Set
	End Property

	Public Property AllowNegative() As Boolean
		Get
			Return _AllowNegative
		End Get
		Set(ByVal Value As Boolean)
			_AllowNegative = Value
		End Set
	End Property

	Private _NumberGrouping As Boolean = True
	Public Property NumberGrouping() As Boolean
		Get
			Return _NumberGrouping
		End Get
		Set(ByVal Value As Boolean)
			_NumberGrouping = Value
		End Set
	End Property

	Private _DollarSign As Boolean = False
	Public Property DollarSign() As Boolean
		Get
			Return _DollarSign
		End Get
		Set(ByVal Value As Boolean)
			_DollarSign = Value
		End Set
	End Property

	Private _ControlWidth As Integer
	Public Property ControlWidth() As Integer
		Get
			Return _ControlWidth
		End Get
		Set(ByVal Value As Integer)
			MyBase.Width = Value
			_ControlWidth = Value
		End Set
	End Property

#End Region

End Class

